package com.boil.qz.safekavass.service;

import com.boil.exception.BaseException;
import com.boil.pojo.ResultVo;
import com.boil.qz.safekavass.dao.MybatisDao;
import com.boil.qz.safekavass.model.LoginUser;
import com.boil.qz.safekavass.model.Question;
import com.boil.qz.safekavass.pojo.QuestionVo;
import com.boil.qz.safekavass.repository.QuestionRepository;
import com.boil.util.Constants;
import com.boil.util.DateUtils;
import com.boil.util.FileUtils;
import com.boil.util.Page;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

/**
 * Created by ChenYong on 2017-04-12.
 * <br>
 * 题库 Service。
 */
@Service
public class QuestionService extends JpaRepositoryService<Question, Long> {
    /**
     * 注入 Mybatis Dao
     */
    @Autowired
    private MybatisDao mybatisDao;
    /**
     * 注入题库实体仓库
     */
    @Autowired
    private QuestionRepository questionRepository;

    /**
     * 分页查询题目。
     *
     * @param page 分页实例
     */
    public void findInPage(Page<QuestionVo> page) {
        mybatisDao.selectInPage("questionVoNs.findInPage", page);
    }

    /**
     * 调存储过程（PR_EXAM_LIB）同步题库。
     */
    public void procPrExamLib() {
        mybatisDao.selectOne("questionVoNs.procPrExamLib");
    }

    /**
     * 处理题库。
     *
     * @param resultVo    结果映射实例
     * @param loginUser   登录用户
     * @param uploadExcel 题库
     * @throws Exception 抛出异常
     */
    public void doQuestion(ResultVo resultVo, LoginUser loginUser, MultipartFile uploadExcel) throws Exception {
        // 上传的 Excel 文件为空
        if ((resultVo == null) || (uploadExcel == null) || uploadExcel.isEmpty()) {
            resultVo.setResultCode(Constants.UPLOAD_EXCEL_EMPTY);
            resultVo.setResultMsg(Constants.UPLOAD_EXCEL_EMPTY_MSG);

            // 上传的 Excel 文件不为空
        } else {
            // Excel 的长度
            long excelLegnth = uploadExcel.getSize();
            // Excel 的后缀名
            String excelSuffix = FileUtils.getFileSuffix(uploadExcel.getOriginalFilename());

            // 不是 Excel
            if (!FileUtils.isExcel(uploadExcel.getOriginalFilename())) {
                resultVo.setResultCode(Constants.UPLOAD_EXCEL_TYPE);
                resultVo.setResultMsg(Constants.UPLOAD_EXCEL_TYPE_MSG);

                // 是 Excel
            } else {
                // Excel 的长度超过最大限制
                if (excelLegnth > Constants.UPLOAD_FILE_MAX_SIZE_50M) {
                    resultVo.setResultCode(Constants.UPLOAD_EXCEL_EXCEED_MAX_SIZE);
                    resultVo.setResultMsg(Constants.UPLOAD_EXCEL_EXCEED_MAX_SIZE_MSG);

                    // Excel 的长度未超过最大限制
                } else {
                    // 采用 Poi 解析 Excel，精彩马上开始
                    // 创建文档对象
                    Workbook workbook = null;
                    // 创建所有表格总题库
                    List<Question> questions = new ArrayList<Question>();

                    // xls ---> Excel
                    if (Constants.SUFFIX_XLS.equals(excelSuffix)) {
                        workbook = new HSSFWorkbook(uploadExcel.getInputStream());

                        // xlsx ---> Excel
                    } else if (Constants.SUFFIX_XLSX.equals(excelSuffix)) {
                        workbook = new XSSFWorkbook(uploadExcel.getInputStream());
                    } else {
                        throw new BaseException(Constants.UPLOAD_EXCEL_TYPE_MSG);
                    }

                    // 获取表格迭代器
                    Iterator<Sheet> sheetIterator = workbook.sheetIterator();

                    while (sheetIterator.hasNext()) {
                        // 获取当前表格，并且指针移动到下一个表格
                        Sheet sheet = sheetIterator.next();
                        // 获取行迭代器
                        Iterator<Row> rowIterator = sheet.rowIterator();
                        // 创建表格题库，即一个表格对应的题库
                        List<Question> sheetQuestions = new ArrayList<Question>();
                        // 迭代器的步进变量
                        int i = Constants.VALUE_0;

                        while (rowIterator.hasNext()) {
                            // 获取当前行，并且指针移动到下一行
                            Row row = rowIterator.next();

                            // 从第三行开始读取题库
                            if (i >= Constants.VALUE_2) {
                                // 保证列数符合规定
                                if ((row.getLastCellNum() - row.getFirstCellNum()) >= Constants.VALUE_9) {
                                    // 创建题目
                                    Question question = new Question();
                                    // 序号
                                    // Cell cell0 = row.getCell(row.getFirstCellNum());
                                    // 行业代码
                                    Cell cell1 = row.getCell(row.getFirstCellNum() + Constants.VALUE_1);
                                    // 学习内容
                                    Cell cell2 = row.getCell(row.getFirstCellNum() + Constants.VALUE_2);
                                    // 题目名称
                                    Cell cell3 = row.getCell(row.getFirstCellNum() + Constants.VALUE_3);
                                    // A 答案
                                    Cell cell4 = row.getCell(row.getFirstCellNum() + Constants.VALUE_4);
                                    // B 答案
                                    Cell cell5 = row.getCell(row.getFirstCellNum() + Constants.VALUE_5);
                                    // C 答案
                                    Cell cell6 = row.getCell(row.getFirstCellNum() + Constants.VALUE_6);
                                    // D 答案
                                    Cell cell7 = row.getCell(row.getFirstCellNum() + Constants.VALUE_7);
                                    // 正确答案
                                    Cell cell8 = row.getCell(row.getFirstCellNum() + Constants.VALUE_8);

                                    question.setIndustryCode((cell1 == null) ? null : cell1.getStringCellValue().trim().toUpperCase(Locale.getDefault()));
                                    question.setDescription((cell2 == null) ? null : cell2.getStringCellValue().trim());
                                    question.setSubjectTitle((cell3 == null) ? null : cell3.getStringCellValue().trim());
                                    question.setAnswerA((cell4 == null) ? null : cell4.getStringCellValue().trim());
                                    question.setAnswerB((cell5 == null) ? null : cell5.getStringCellValue().trim());
                                    question.setAnswerC((cell6 == null) ? null : cell6.getStringCellValue().trim());
                                    question.setAnswerD((cell7 == null) ? null : cell7.getStringCellValue().trim());
                                    question.setCreateTime(DateUtils.format(new Date(), Constants.DATE_TIME_FORMAT_1));

                                    // 如果行业代码和题目名称其中一个为空，中断本次循环，姿势要正确才行
                                    if (StringUtils.isBlank(question.getIndustryCode()) || StringUtils.isBlank(question.getSubjectTitle())) {
                                        continue;
                                    }

                                    // 单选题
                                    if (cell8 == null) {
                                        question.setIsDouble(String.valueOf(Constants.VALUE_0));

                                        // 判断是单选题还是多选题
                                    } else {
                                        String cellValue = cell8.getStringCellValue();

                                        // 单选题
                                        if (StringUtils.isBlank(cellValue)) {
                                            cellValue = cellValue.trim();

                                            question.setIsDouble(String.valueOf(Constants.VALUE_0));

                                            // 判断是单选题还是多选题
                                        } else {
                                            // 去掉所有空白符，并转换为大写
                                            cellValue = cellValue.trim()
                                                    .replaceAll("\\s+", "")
                                                    .replace("Ａ", "A")
                                                    .replace("Ｂ", "B")
                                                    .replace("Ｃ", "C")
                                                    .replace("Ｄ", "D")
                                                    .toUpperCase(Locale.getDefault());

                                            // 单选题
                                            if (cellValue.length() == Constants.VALUE_1) {
                                                question.setIsDouble(String.valueOf(Constants.VALUE_0));

                                                // 多选题
                                            } else {
                                                question.setIsDouble(String.valueOf(Constants.VALUE_1));

                                                // 分隔答案
                                                String[] values = cellValue.split("");
                                                // 给答案升序排序
                                                Arrays.sort(values, new Comparator<String>() {
                                                    public int compare(String s1, String s2) {
                                                        if (StringUtils.isBlank(s1) || StringUtils.isBlank(s2)) {
                                                            return Constants.VALUE_0;
                                                        }

                                                        return s1.compareTo(s2);
                                                    }
                                                });

                                                // 拼接答案
                                                StringBuilder sbValue = new StringBuilder();
                                                for (String value : values) {
                                                    sbValue.append(value);
                                                }

                                                // 最后得到完美的答案
                                                cellValue = sbValue.toString();
                                            }
                                        }

                                        question.setRightAns(cellValue);
                                    }

                                    sheetQuestions.add(question);
                                }
                            }

                            // 向前一小步
                            i++;
                        }

                        questions.addAll(sheetQuestions);
                    }

                    // 保存到数据库
                    save(questions);
                    // 调存储过程（PR_EXAM_LIB）同步题库
                    procPrExamLib();

                    resultVo.setResultCode(Constants.SUCCESS);
                    resultVo.setResultMsg(Constants.UPLOAD_SUCCESS_MSG);

                    workbook = null;
                    uploadExcel = null;

                    log.info("账号：{}，题目总数量：{}，保存题目数量：{}--->上传题库成功", loginUser.getLoginid(), questions.size(), questions.size());
                }
            }
        }
    }
}